package hk.ust.cse.comp4981;

import java.io.IOException;
import java.text.Format;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;

import org.apache.commons.lang.StringUtils;

public class NyClusters {

	static jdbcmysql test = new jdbcmysql();
	static Format formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

	// n-grams cluster position in ArrayList
	final static int ONE_GRAM = 0;
	final static int TWO_GRAM = 1;
	final static int THREE_GRAM = 2;
	final static int FOUR_GRAM = 3;
	final static int FIVE_GRAM = 4;

	// cluster result
	private static ArrayList<ArrayList<Result>> alGroupedMaxNgramTweet = new ArrayList<ArrayList<Result>>();
	private static ArrayList<Result> alinner1 = new ArrayList<Result>();
	private static ArrayList<Result> alinner2 = new ArrayList<Result>();
	private static ArrayList<Result> alinner3 = new ArrayList<Result>();
	private static ArrayList<Result> alinner4 = new ArrayList<Result>();
	private static ArrayList<Result> alinner5 = new ArrayList<Result>();
	private static ArrayList<ArrayList<Result>> alResNgramCluster = new ArrayList<ArrayList<Result>>();
	private static ArrayList<Result> alcluster1 = new ArrayList<Result>();
	private static ArrayList<Result> alcluster2 = new ArrayList<Result>();
	private static ArrayList<Result> alcluster3 = new ArrayList<Result>();
	private static ArrayList<Result> alcluster4 = new ArrayList<Result>();
	private static ArrayList<Result> alcluster5 = new ArrayList<Result>();

	private static ArrayList<Result> Event = new ArrayList<Result>();

	public NyClusters() {
		super();
	}

	public static void cluster() {

		System.out.println("Clusters:");

		// adding references to inner
		alGroupedMaxNgramTweet.add(alinner1); // add the ONE_GRAM list
		alGroupedMaxNgramTweet.add(alinner2); // add the TWO_GRAM list
		alGroupedMaxNgramTweet.add(alinner3); // add the THREE_GRAM list
		alGroupedMaxNgramTweet.add(alinner4); // add the FOUR_GRAM list
		alGroupedMaxNgramTweet.add(alinner5); // add the FIVE_GRAM list

		float fMaxTfidfOfCluster[] = { Float.MIN_VALUE, Float.MIN_VALUE,
				Float.MIN_VALUE, Float.MIN_VALUE, Float.MIN_VALUE };

		for (int i = 0; i < tfidf.alMaxNgramTweet.size(); i++) {

			// assign the max tokens and its tfidf score to different n-grams
			switch (tfidf.alMaxNgramTweet.get(i).getNgram()) {
			case 1:
				if (tfidf.alMaxNgramTweet.get(i).getWord() != "") {
					alGroupedMaxNgramTweet.get(ONE_GRAM).add(
							tfidf.alMaxNgramTweet.get(i));
					if (tfidf.alMaxNgramTweet.get(i).getScore() > fMaxTfidfOfCluster[ONE_GRAM])
						fMaxTfidfOfCluster[ONE_GRAM] = tfidf.alMaxNgramTweet
								.get(i).getScore();
					break;
				}
			case 2:
				alGroupedMaxNgramTweet.get(TWO_GRAM).add(
						tfidf.alMaxNgramTweet.get(i));
				if (tfidf.alMaxNgramTweet.get(i).getScore() > fMaxTfidfOfCluster[TWO_GRAM])
					fMaxTfidfOfCluster[TWO_GRAM] = tfidf.alMaxNgramTweet.get(i)
							.getScore();
				break;
			case 3:
				alGroupedMaxNgramTweet.get(THREE_GRAM).add(
						tfidf.alMaxNgramTweet.get(i));
				if (tfidf.alMaxNgramTweet.get(i).getScore() > fMaxTfidfOfCluster[THREE_GRAM])
					fMaxTfidfOfCluster[THREE_GRAM] = tfidf.alMaxNgramTweet.get(
							i).getScore();

				break;
			case 4:
				alGroupedMaxNgramTweet.get(FOUR_GRAM).add(
						tfidf.alMaxNgramTweet.get(i));
				if (tfidf.alMaxNgramTweet.get(i).getScore() > fMaxTfidfOfCluster[FOUR_GRAM])
					fMaxTfidfOfCluster[FOUR_GRAM] = tfidf.alMaxNgramTweet
							.get(i).getScore();
				break;
			case 5:
				alGroupedMaxNgramTweet.get(FIVE_GRAM).add(
						tfidf.alMaxNgramTweet.get(i));
				if (tfidf.alMaxNgramTweet.get(i).getScore() > fMaxTfidfOfCluster[FIVE_GRAM])
					fMaxTfidfOfCluster[FIVE_GRAM] = tfidf.alMaxNgramTweet
							.get(i).getScore();
				break;
			}

		}

		alResNgramCluster.add(alcluster1);
		alResNgramCluster.add(alcluster2);
		alResNgramCluster.add(alcluster3);
		alResNgramCluster.add(alcluster4);
		alResNgramCluster.add(alcluster5);

		for (int j = 0; j < alGroupedMaxNgramTweet.size(); j++) {
			System.out.println(j + 1 + "GRAM: "
					+ alGroupedMaxNgramTweet.get(j).toString());

			for (int k = 0; k < alGroupedMaxNgramTweet.get(j).size(); k++) {
				if (alGroupedMaxNgramTweet.get(j).get(k).getScore() >= fMaxTfidfOfCluster[j])
					alResNgramCluster.get(j).add(
							alGroupedMaxNgramTweet.get(j).get(k));
			}
		}

		for (int j = 0; j < alResNgramCluster.size(); j++) {
			System.out.println("Max in cluster " + (j + 1)
					+ alResNgramCluster.get(j).toString());
		}

		// compare the results

		for (int i = 4; i > 0; i--) { // run for 5 clusters

			for (Result biggerCluster : alResNgramCluster.get(i)) {
				String strBiggerCluster = biggerCluster.getWord();
				boolean bHitAny = false;
				for (int j = i - 1; j >= 0; j--) {

					for (Result smallerCluster : alResNgramCluster.get(j)) {
						if (StringUtils.containsIgnoreCase(strBiggerCluster,
								smallerCluster.getWord())) {
							biggerCluster.getHit().add(smallerCluster);
							bHitAny = true;
						}
					}
				}
				// record the hit one
				if (bHitAny) {
					Event.add(biggerCluster);
				}
			}

		}

		// sort Event by # of hit
		Collections.sort(Event);

		// show sorted event
		/*
		 * for (Result e : Event) { System.out.print("Event: " + e.getWord());
		 * 
		 * for (Result hit : e.getHit()) { System.out.print(" (" + hit.getWord()
		 * + ")"); } System.out.println(); }
		 */

		// output most 5 max. Hit events
		String currentTime;
		currentTime = formatter.format(System.currentTimeMillis());
		for (int i = 0; i < 5; i++) {
			// insert NY events into database, country code for New York is 1
			test.insertTable_event(currentTime, Event.get(i).getWord(), 1);

			// testing the clustering
			/*
			 * System.out.print("Event: " + Event.get(i).getWord());
			 * 
			 * for (Result hit : Event.get(i).getHit()) { System.out.print(" ("
			 * + hit.getWord() + ")"); } System.out.println();
			 */
		}

	}

}